package SwingModel;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

import JDBC.InstructorGradebookActivities;
import JDBC.InstructorAssignmentActivities;
import SwingController.CmsPresenter;

public class CmsGradebook extends AbstractTableModel{

	public final String collumnNames[];
	public final List<Object[]> data;
	public final List<CmsAssignment> asgms;
	public final List<CmsQuiz> quizzes;
	public final List<CmsStudent> students;
	
	public CmsGradebook(List<CmsStudent> students, List<CmsAssignment> asgms, List<CmsQuiz> quizzes){
		this.asgms = asgms;
		this.quizzes = quizzes;
		this.students = students;
		data = new ArrayList();
		
		collumnNames = new String[asgms.size() + quizzes.size() + 2];
		collumnNames[0] = "Students";
		double totalWeight = 0.0d;
		int c = 1;
		for(CmsAssignment asgm : asgms){
			collumnNames[c] = asgm.getAsgmTitle() + " (" + asgm.getPercentWeight()+ "%)";
			totalWeight += asgm.getPercentWeight();
			c++;
		}
		for(CmsQuiz quiz : quizzes){
			collumnNames[c] = quiz.getQuizTitle() + " (" + quiz.getPercentWeight() + "%)";
			totalWeight += quiz.getPercentWeight();
			c++;
		}
		collumnNames[c] = "Total Grade Average\n(out of " + totalWeight + "%)";
		
		//GET GRADE DATA
		for(CmsStudent student : students){ // for each student
			Object[] studentEntry = new Object[asgms.size() + quizzes.size() + 2];// # of column = asgms + quizzes + 1 column for student name
			
			studentEntry[0] = new String(student.getFirstName() + " " + student.getLastName());
			
			int i = 1;
			double gradeAve = 0.0;
			for(CmsAssignment asgm : asgms){
				double asgmGrade = InstructorGradebookActivities.getAsgmGrade(student.getUsername(), asgm.getAsgmID());
				studentEntry[i] = asgmGrade;
				gradeAve += asgmGrade * asgm.getPercentWeight() / 100.0d;
				i++;
			}
			for(CmsQuiz quiz : quizzes){
				double quizGrade = InstructorGradebookActivities.getQuizGrade(student.getUsername(), quiz.getQuizID());
				studentEntry[i] = quizGrade;
				gradeAve += quizGrade * quiz.getPercentWeight()/ 100.0d;
				i++;
			}
			studentEntry[i] = ""+ gradeAve + "%";
			data.add(studentEntry);
		}
	}
	
	@Override
	public int getRowCount() {
		return data.size();
	}

	@Override
	public int getColumnCount() {
		return collumnNames.length;
	}

	@Override
	public String getColumnName(int col){
		return collumnNames[col];
	}
	
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		
		return ( data.get(rowIndex) )[columnIndex];
	}

	@Override
	public boolean isCellEditable(int row, int col) { // set which cell are editable
        if (col <= asgms.size() && col > 0) {
            return true;
        } else {
            return false;
        }
    }
	

    public void setValueAt(Object value, int row, int col) {
    	
    	try{
    		double parsedValue = Double.parseDouble( (String)value );
    		if(parsedValue >= 0.0d && parsedValue < 150.0d){
    			data.get(row)[col] = value;
                fireTableCellUpdated(row, col);
                InstructorAssignmentActivities.updateGrade(asgms.get(col - 1).getAsgmID(), students.get(row).getUsername(), parsedValue);
    		}
    		else{
    			JOptionPane.showMessageDialog(CmsPresenter.mainView, "ERROR: Grade has to  be between 0.0% and 150.0%","ERROR", JOptionPane.ERROR_MESSAGE);
    		}
    		
    	}
    	catch (Exception e){
    		JOptionPane.showMessageDialog(CmsPresenter.mainView,"ERROR: Invalid input!\nPlease enter a number value between 0.0 and 150.0","ERROR",JOptionPane.ERROR_MESSAGE );
    	}
        
    }
    
    @Override
    public String toString(){
    	StringBuilder str = new StringBuilder();
    	for(String cn : collumnNames){
    		str.append(cn + "\t");
    	}
    	str.append("\n");
    	for(Object[] o : data){
    		for( Object i : o){
    			str.append(i + "\t");
    		}
    		str.append("\n");
    	}
    	return str.toString();
    }
}
